package com.funi.demo;

import com.funi.consts.Constants;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.GitLabApiException;
import org.gitlab4j.api.models.Branch;
import org.gitlab4j.api.models.Commit;
import org.gitlab4j.api.models.Project;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**********************************************************************
 * &lt;p&gt;文件名：GitlabMain.java &lt;/p&gt;
 * &lt;p&gt;文件描述：(描述该文件做什么)
 * @project_name：code_total
 * @author zengshunyao
 * @create 2025/5/28 18:03
 * @history
 * @department：政务事业部
 * Copyright ChengDu Funi Cloud Code Technology Development CO.,LTD 2014
 *                    All Rights Reserved.
 */

public class GitlabMain {

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    private static final String GITLAB_URL = Constants.GITLAB_URL;
    private static final String PERSONAL_ACCESS_TOKEN = Constants.PERSONAL_ACCESS_TOKEN;

    /**
     * @throws GitLabApiException
     */
    public static void main(String[] args) throws Exception {
        GitLabApi gitLabApi = new GitLabApi(GITLAB_URL, PERSONAL_ACCESS_TOKEN);
        gitLabApi.getGroupApi().getGroups().forEach(e -> {
            System.out.println(e.getId() + "-" + e.getName());
        });

        StringBuilder sb = new StringBuilder(gitlab61());
        //.append(gitlab104())
        //.append(gitlab97());
        System.out.println(sb);
    }

    /**
     * 2-DC
     *
     * @throws GitLabApiException
     */
    public static String gitlab61() throws Exception {
        List<Integer> groupIds = Lists.newArrayList(2);
        return gitlab(GITLAB_URL, PERSONAL_ACCESS_TOKEN, "2025-08-01 00:00:00", "2025-09-01 00:00:00", groupIds);
    }

    /**
     * 3-dfh
     *
     * @throws GitLabApiException
     */
    public static String gitlab97() throws Exception {
        List<Integer> groupIds = Lists.newArrayList(3);
        return gitlab("xxxxxx", "xxxxx", "2022-08-01 00:00:00", "2022-09-01 00:00:00", groupIds);
    }

    /**
     * #13 dfh
     * #34 dfham-smart-research
     * #59 nibp
     * #58 pms
     */
    public static String gitlab104() throws Exception {
        List<Integer> groupIds = Lists.newArrayList(13, 34, 59, 58);
        return gitlab("xxxxx", "xxxxx", "2022-07-01 00:00:00", "2022-07-31 23:59:59", groupIds);
    }

    public static String gitlab(String url, String token, String startDate, String endDate, List<Integer> groupIds) throws ParseException {
        Date BEGIN_DATE = sdf.parse(startDate);
        Date END_DATE = sdf.parse(endDate);
        Map<String, Map<String, CommitVo>> result = new HashMap<>();
        // 获取连接
        // hostUrl：gitLab的域名（或者IP:port）
        // personalAccessToken：步骤2中的AccessToken
        GitLabApi gitLabApi = new GitLabApi(url, token);
        // 条件获取project
        // nameSpace：项目的命名空间
        // projectName：项目名称
        groupIds.forEach(e -> {
            List<Project> projects = null;
            try {
                projects = gitLabApi.getGroupApi().getProjects(e);
            } catch (GitLabApiException gitLabApiException) {
                gitLabApiException.printStackTrace();
            }
            if (!CollectionUtils.isEmpty(projects)) {
                projects.forEach(p -> {
                    Map<String, CommitVo> map = result.computeIfAbsent(p.getName(), key -> new HashMap<>());
                    //System.out.println(p.getNamespace().getName() + "-" + p.getId() + "-" + p.getName());
                    List<Branch> branches = null;
                    try {
                        branches = gitLabApi.getRepositoryApi().getBranches(p.getId());
                    } catch (GitLabApiException gitLabApiException) {
                        gitLabApiException.printStackTrace();
                    }
                    if (!CollectionUtils.isEmpty(branches)) {
                        branches.forEach(b -> {
                            try {
                                List<Commit> commits = gitLabApi.getCommitsApi().getCommits(p.getId(), b.getName(), BEGIN_DATE, END_DATE);
                                if (!CollectionUtils.isEmpty(commits)) {
                                    commits.forEach(v -> {
                                        try {
                                            v = gitLabApi.getCommitsApi().getCommit(p.getId(), v.getShortId());
                                        } catch (GitLabApiException gitLabApiException) {
                                            gitLabApiException.printStackTrace();
                                        }
                                        CommitVo vo = map.computeIfAbsent(v.getAuthorName() + "-" + v.getAuthorEmail(), key -> new CommitVo());
                                        vo.setAddCount(vo.getAddCount() + v.getStats().getAdditions());
                                        vo.setDeleteCount(vo.getDeleteCount() + v.getStats().getDeletions());
                                        vo.setTotalCount(vo.getTotalCount() + v.getStats().getTotal());
                                    });
                                }
                            } catch (GitLabApiException ioException) {
                                ioException.printStackTrace();
                            }
                        });
                    }
                });
            }
        });

        StringBuilder sb = new StringBuilder();

        result.entrySet().forEach(e -> {
            e.getValue().entrySet().forEach(ee -> {
                sb.append(e.getKey() + "\t" + ee.getKey() + "\t" + ee.getValue().getAddCount() + "\t" + ee.getValue().getDeleteCount() + "\t" + ee.getValue().getTotalCount()).append("\r\n");
            });
        });

        return sb.toString();
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class CommitVo {
        private Integer addCount = 0;
        private Integer deleteCount = 0;
        private Integer totalCount = 0;
    }


}
